from  datetime import datetime
import functools
import traceback
from tkinter import messagebox
import tkinter as tk
import logging
import numpy as np

logging.basicConfig(filename='./AutoFocus.log', level=logging.INFO)

def r2_score(y_true,y_pred):
    # 计算相关系数
    corr = np.corrcoef(y_true, y_pred)[0, 1]
    # 计算 R 方值
    r2 = corr ** 2
    return r2

def corrcoef(X,y):
    corr = np.corrcoef(X, y, rowvar=False)
    cor1=(corr[0,1],corr[1,2])
    return cor1


class LinearRegression:
    def __init__(self):
        self.theta = None

    def fit(self, X, y):
        """
        训练线性回归模型

        参数：
        X：自变量数据，形状为 (m, n)，其中 m 是样本数量，n 是特征数量
        y：因变量数据，形状为 (m, 1)
        """
        # 在 X 前面加一列1，以便于计算截距项
        X_b = np.c_[np.ones((X.shape[0], 1)), X]

        # 使用正规方程求解回归系数
        self.theta = np.linalg.inv(X_b.T @ X_b) @ X_b.T @ y

    def predict(self, X):
        """
        对新样本进行预测

        参数：
        X：自变量数据，形状为 (m, n)，其中 m 是样本数量，n 是特征数量

        返回值：
        y_pred：预测的因变量数据，形状为 (m, 1)
        """
        if self.theta is None:
            raise ValueError("模型未经过训练，请先调用 fit 方法")

        # 在 X 前面加一列1，以便于计算截距项
        X_b = np.c_[np.ones((X.shape[0], 1)), X]

        # 使用训练得到的回归系数进行预测
        y_pred = X_b @ self.theta

        return y_pred

def show_info_message():
    messagebox.showinfo("Information", "This is an information message.")

def show_warning_message():
    messagebox.showwarning("Warning", "This is a warning message.")

def show_error_message():
    messagebox.showerror("Error", "This is an error message.")

def handle_exceptions(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        try:
            return func(*args, **kwargs)
        except Exception as e:
            #获取异常类型
            error_type = type(e).__name__
            # 获取异常信息
            error_message = str(e)
            # 打印错误堆栈跟踪到控制台
            traceback.print_exc()
            messagebox.showerror("Error", f'An error of type {error_type} occurred: {error_message}')
    return wrapper

# 获取当前日期和时间
def get_current_datetime():
    now = datetime.now()
    return now.strftime("%Y-%m-%d %H:%M:%S")

class TextRedirector(object):
    def __init__(self, text_widget,log2file=False):
        self.text_widget = text_widget
        self.log2file=log2file

    def write(self, msg):
        if(self.text_widget):
            self.text_widget.configure(state='normal')
            self.text_widget.insert(tk.END, msg)
            self.text_widget.configure(state='disabled')
            self.text_widget.yview(tk.END)  # Auto-scroll to the end
        if(self.log2file and msg!='\n'):
            log_message = f"{get_current_datetime()} - {msg}"
            logging.info(log_message)

    def flush(self):
        pass  # For compatibility with Python's default stdout

